<template>
  <div class="goods-sku">
    <div class="choseGroup" v-for="item in goods.specs" :key="item.id">
      <span class="description">{{ item.name }}</span>
      <div class="chose">
        <template v-for="val in item.values" :key="val.name">
          <img
            :class="{ selected: val.selected, disabled: val.disabled }"
            @click="clickSpecs(item, val)"
            v-if="val.picture"
            :src="val.picture"
            :title="val.name"
          />
          <span
            :class="{ selected: val.selected, disabled: val.disabled }"
            @click="clickSpecs(item, val)"
            v-else
            >{{ val.name }}</span
          >
        </template>
      </div>
    </div>
  </div>
</template>
<script>
</script>
<script setup name="GoodsSku">
import { defineProps, defineEmits } from "vue";
import getPowerSet from '@/vender/power-set'
const props = defineProps({
  goods: {
    type: Object,
    default: () => ({})
  },
  goodsId: {
    type: String,
    default: ''
  }
});
const emit = defineEmits(['changeSKU'])


// 《选择》
const clickSpecs = (item, val) => {
  // 如果是禁用状态不作为
  if (val.disabled) return
  if (val.selected) {
    val.selected = false
  } else {
    item.values.forEach(el => { el.selected = false });
    val.selected = true
  }
  updateDisabledStatus(props.goods.specs, pathMap)

  // 响应父组件，传出完整信息
  const currSpec = getSelectedArr(props.goods.specs)
  if (!currSpec.includes(undefined)) {
    // 完整路径👇
    const key = currSpec.join(star)
    const SKUID = pathMap[key]
    console.log(SKUID);
    const SKU = props.goods.skus.find(item => item.id === SKUID[0])
    emit('changeSKU', SKU)
  }
}

// 得到当前选中规格集合
const getSelectedArr = (specs) => {
  const arr = []
  specs.forEach(spec => {
    const obj = spec.values.find(val => val.selected)
    arr.push(obj ? obj.name : undefined)
  })
  return arr
}

// 初始化选中项
const initCartSelect = (skuId) => {
  const selectItem = props.goods.skus.find(item => item.id === skuId)
  if (selectItem) {
    props.goods.specs.forEach((spec, index) => {
      const name = selectItem.specs[index].valueName
      spec.values.forEach(val => { val.selected = val.name === name })
    })
  }
}

// 更新按钮的禁用状态
const updateDisabledStatus = (specs, pathMap) => {
  specs.forEach((spec, index) => {
    const curr = getSelectedArr(specs)
    spec.values.forEach(val => {
      // 循环遍历所有下一次点击可选按钮，然后跑字典，disabled所有字典中没有的路线
      if (val.selected) return
      curr[index] = val.name
      // 👇filter跳过所有undefined，拼串
      const key = curr.filter(v => v).join(star)
      val.disabled = !pathMap[key]
    })
  })
}

// 根据skus数据得到路径字典对象
const star = '★'
const getPathMap = (skus) => {
  const pathMap = {}
  skus.forEach(sku => {
    // 1. 过滤出有库存有效的sku
    if (sku.inventory) {
      // 2. 得到sku属性值数组
      const specs = sku.specs.map(spec => spec.valueName)
      // 3. 得到sku属性值数组的子集
      const powerSet = getPowerSet(specs)
      // 4. 设置给路径字典对象
      powerSet.forEach(set => {
        const key = set.join(star)
        // 没有key设置一个数组，用于存放 skuid
        if (!pathMap[key]) pathMap[key] = []
        // 往数组追加 skuid
        pathMap[key].push(sku.id)
      })
    }
  })
  return pathMap
}
// 获取字典列表
const pathMap = getPathMap(props.goods.skus)
initCartSelect(props.goodsId)
updateDisabledStatus(props.goods.specs, pathMap)

</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  .choseGroup {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    .description {
      width: 50px;
      color: #999;
    }
    .chose {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        margin-bottom: 10px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
